home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume12 / rot / part01 next >
Encoding:
Text File  |  1990-05-05  |  11.7 KB  |  538 lines

  1. Newsgroups: comp.sources.misc
  2. organization: Xenix Support, FICC
  3. subject: v12i016: ROT -- demonstrate bitrot. Release 12/89. Update 04/90.
  4. from: peter@ficc.uu.net (Peter da Silva)
  5. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  6.  
  7. Posting-number: Volume 12, Issue 16
  8. Submitted-by: peter@ficc.uu.net (Peter da Silva)
  9. Archive-name: rot/part01
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of shell archive."
  18. # Contents:  Makefile rot.c
  19. # Wrapped by peter@ficc.uu.net on Sun Apr 29 10:44:59 1990
  20. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  21. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  22.   echo shar: Will not clobber existing file \"'Makefile'\"
  23. else
  24. echo shar: Extracting \"'Makefile'\" \(129 characters\)
  25. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  26. X# Simple makefile for rot program
  27. X
  28. XCFLAGS = -O #-DSYSV
  29. X
  30. Xrot:    rot.c
  31. X    cc $(CFLAGS) -o rot rot.c -ltermlib
  32. X
  33. Xtest:    rot
  34. X    ./rot <rot.c
  35. END_OF_FILE
  36. if test 129 -ne `wc -c <'Makefile'`; then
  37.     echo shar: \"'Makefile'\" unpacked with wrong size!
  38. fi
  39. # end of 'Makefile'
  40. fi
  41. if test -f 'rot.c' -a "${1}" != "-c" ; then 
  42.   echo shar: Will not clobber existing file \"'rot.c'\"
  43. else
  44. echo shar: Extracting \"'rot.c'\" \(9548 characters\)
  45. sed "s/^X//" >'rot.c' <<'END_OF_FILE'
  46. X/*
  47. X * Revision History:
  48. X *
  49. X * Original source from:
  50. X *  Peter da Silva (ihnp4!shell!neuro1!{hyd-ptd,datafact,baylor}!peter)
  51. X *
  52. X * Changes for padding added by:
  53. X *  Andrew Scott Beals ({ucbvax,decwrl}!amdcad!bandy or bandy@amdcad.amd.com)
  54. X *  20 April 1987
  55. X *
  56. X * Additional changes for padding, fix for computation of tglen,
  57. X * increase max lines, improve termlib handling, add System V #ifdefs.
  58. X *  Bill Randle (billr@tekred.TEK.COM)
  59. X *  21 April 1987
  60. X *
  61. X * Some long-standing 8-bit bugs fixed, and more randomness added.
  62. X *  Peter da Silva <peter@sugar.hackercorp.com> Dec 1 1989.
  63. X */
  64. X
  65. X#include <stdio.h>
  66. X
  67. X#ifdef SYSV
  68. X# include <termio.h>
  69. X#else
  70. X# include <sgtty.h>
  71. X#endif
  72. X
  73. X/*        -- Miscellaneous defines --                     */
  74. X#define FALSE 0
  75. X#define TRUE 1
  76. X#define MAXCOL 80
  77. X#define MAXLI 34
  78. X
  79. Xextern char *tgetstr();
  80. X
  81. Xint lastx, lasty;
  82. Xstruct _c {
  83. X    struct _c *c_next;
  84. X    int c_line, c_column;
  85. X    char c_mark;
  86. X} *clist;
  87. X
  88. X/*        -- Global variables --                         */
  89. Xchar *tent;                                               /* Pointer to tbuf */
  90. Xextern char PC;                                             /* Pad character */
  91. Xextern char *UP, *BC;                         /* Upline, backsapce character */
  92. Xextern short ospeed;                                /* Terminal output speed */
  93. Xint tglen;
  94. X
  95. Xchar *cm,                                                   /* Cursor motion */
  96. X     *cl,                                                    /* Clear screen */
  97. X     *ti,                            /* Init terminal */
  98. X     *te;                           /* Reset terminal */
  99. Xint  li,                                                  /* lines on screen */
  100. X     co;                                                    /* columns ditto */
  101. Xchar screen[MAXLI+1][MAXCOL];
  102. Xchar newscreen[MAXLI+1][MAXCOL];
  103. X
  104. X/* Options */
  105. Xint packflag = 0;
  106. X
  107. Xmain(ac, av)
  108. Xint ac;
  109. Xchar **av;
  110. X{
  111. X    /* set ospeed so padding works correctly */
  112. X#ifdef SYSV
  113. X    struct termio    p;
  114. X
  115. X    if(ioctl(1, TCGETA, &p) != -1)
  116. X        ospeed=p.c_cflag & CBAUD;
  117. X#else
  118. X    struct sgttyb    p;
  119. X
  120. X    if(ioctl(1, TIOCGETP, &p) != -1)
  121. X        ospeed=p.sg_ospeed;
  122. X#endif
  123. X
  124. X    srand(getpid());
  125. X    tinit(getenv("TERM"));
  126. X    while(av[1][0]=='-') {
  127. X        while(av[1][1]) {
  128. X            switch(av[1][1]) {
  129. X                case 'p': packflag=1; break;
  130. X                default: printf("rot [-p] [file]...\n");
  131. X            }
  132. X            av[1]++;
  133. X        }
  134. X        av++;
  135. X    }
  136. X    if(av[1])
  137. X        while(*++av)
  138. X            dropf(*av);
  139. X    else
  140. X        fdropf(stdin);
  141. X    tend();
  142. X}
  143. X
  144. Xat(x, y, c)
  145. Xint x, y;
  146. Xchar c;
  147. X{
  148. X#ifdef DEBUG
  149. X    _at(x, y);
  150. X#else
  151. X    if(y==lasty) {
  152. X        if(x!=lastx) {
  153. X            if(x<lastx && lastx-x<tglen)
  154. X                while(x<lastx) {
  155. X                    putchar('\b');
  156. X                    lastx--;
  157. X                }
  158. X            else if(x>lastx && x-lastx<tglen)
  159. X                while(x>lastx) {
  160. X                    putchar(0x7F&newscreen[lasty][lastx]);
  161. X                    lastx++;
  162. X                }
  163. X            else
  164. X                _at(x, y);
  165. X        }
  166. X    } else
  167. X        _at(x, y);
  168. X#endif
  169. X    c &= 0x7F;
  170. X    putchar(c);
  171. X    if(c >= ' ' && c != '\177')
  172. X        lastx++;
  173. X    if(lastx>=co) {
  174. X        lastx -= co;
  175. X        lasty++;
  176. X    }
  177. X}
  178. X
  179. X_at(x, y)
  180. Xint x, y;
  181. X{
  182. X    extern void    outc();
  183. X
  184. X    tputs(tgoto(cm, x, y), 1, outc);     /* handle padding */
  185. X    lastx = x;
  186. X    lasty = y;
  187. X}
  188. X
  189. Xvoid
  190. Xoutc(c)
  191. Xregister c;
  192. X{
  193. X    putc(c&0x7F, stdout);
  194. X}
  195. X
  196. Xtinit(name)
  197. Xchar *name;
  198. X{
  199. X    static char junkbuf[1024], *junkptr;
  200. X    char tbuf[1024];
  201. X    int  intr();
  202. X
  203. X    junkptr = junkbuf;
  204. X
  205. X    tgetent(tbuf, name);
  206. X
  207. X    if (!tgetflag("bs"))        /* is backspace not used? */
  208. X        BC = tgetstr("bc",&junkptr);    /* find out what is */
  209. X    else
  210. X        BC = "\b";        /* make a backspace handy */
  211. X    if (tgetstr("pc", &junkptr) != NULL)
  212. X        PC = *junkptr;  /* set pad character */
  213. X    else
  214. X        PC = '\0';
  215. X    UP = tgetstr("up", &junkptr);
  216. X    cm = tgetstr("cm", &junkptr);
  217. X    if (cm == NULL) {
  218. X        printf("Can't rot on dumb terminals.\n");
  219. X        exit(1);
  220. X    }
  221. X    cl = tgetstr("cl", &junkptr);
  222. X    ti = tgetstr("ti", &junkptr);
  223. X    te = tgetstr("te", &junkptr);
  224. X    li = min(tgetnum("li"), MAXLI);
  225. X    if (li == -1)
  226. X        li = 24;
  227. X    co = min(tgetnum("co"), MAXCOL);
  228. X    if (co == -1)
  229. X        co = 80;
  230. X    tglen = strlen(tgoto(cm, co-1, li-1));
  231. X}
  232. X
  233. Xtend()
  234. X{
  235. X    outs(te);
  236. X    _at(0, li-1);
  237. X    putchar('\n');
  238. X    fflush(stdout);
  239. X}
  240. X
  241. Xreadscreen(fp)
  242. XFILE *fp;
  243. X{
  244. X    int line, column, p;
  245. X    char tmp[256];
  246. X
  247. X    for(line=0; line<li; line++)
  248. X        for(column=0; column<co; column++)
  249. X            newscreen[line][column] = screen[line][column] = ' ';
  250. X    for(column=0; column<co; column++)
  251. X        newscreen[li][column] = screen[li][column] = '*';
  252. X    line=0;
  253. X    while(line<li) {
  254. X        if(!fgets(tmp, 256, fp))
  255. X            return;
  256. X
  257. X        for(column=0, p=0; tmp[p]; p++) {
  258. X            tmp[p] &= ~0200;
  259. X            if(tmp[p] < ' ' || tmp[p] == 127)
  260. X                switch(tmp[p]) {
  261. X                    case '\t':
  262. X                        while(++column % 8)
  263. X                            continue;
  264. X                        break;
  265. X                    case '\n':
  266. X                        column = 0;
  267. X                        line++;
  268. X                        break;
  269. X                    default:
  270. X                        newscreen[line][column] = '^';
  271. X                        column++;
  272. X                        if(column>=co) {
  273. X                            column -= co;
  274. X                            line++;
  275. X                        }
  276. X                        newscreen[line][column] =
  277. X                            (tmp[p]+'@') & 127;
  278. X                        column++;
  279. X                        break;
  280. X                }
  281. X            else {
  282. X                newscreen[line][column] = tmp[p];
  283. X                column++;
  284. X            }
  285. X            if(column >= co) {
  286. X                column -= co;
  287. X                line++;
  288. X            }
  289. X            if(line >= li)
  290. X                break;
  291. X        }
  292. X    }
  293. X    for(column=0; column<co; column++)
  294. X        newscreen[line][column] = screen[li][column] = '*';
  295. X}
  296. X
  297. Xdrawscreen()
  298. X{
  299. X    lastx = lasty = 0;
  300. X    outs(cl);
  301. X    update();
  302. X}
  303. X
  304. Xupdate() /* copy new screen back to old screen */
  305. X{
  306. X    int l, c;
  307. X
  308. X    for(l=0; l<li; l++)
  309. X        for(c=0; c<co; c++)
  310. X            if(screen[l][c] != newscreen[l][c]) {
  311. X                if((screen[l][c] & ~0200) !=
  312. X                   (newscreen[l][c] & ~0200))
  313. X                    at(c, l, newscreen[l][c]);
  314. X                screen[l][c] = newscreen[l][c];
  315. X            }
  316. X}
  317. X
  318. Xdrop(line, column)
  319. Xint line, column;
  320. X{
  321. X    struct _c *hold, *temp;
  322. X
  323. X    if(line<0 || line>=li || column<0 || column>=co ||
  324. X       (line>=li-2 && column >= co-1) || /* scroll potential */
  325. X       screen[line][column]==' ' || /* empty */
  326. X       screen[line][column] & 0200) /* already in list */
  327. X        return;
  328. X    if(screen[line+1][column]!=' ' &&
  329. X       (column==co-1 ||screen[line+1][column+1]!=' ') &&
  330. X       (column==0 ||screen[line+1][column-1]!=' '))
  331. X        return;
  332. X
  333. X    hold = (struct _c *) malloc(sizeof(struct _c));
  334. X    hold -> c_next;
  335. X    hold -> c_column = column;
  336. X    hold -> c_line = line;
  337. X    hold -> c_mark = 0;
  338. X    screen[line][column] |= 0200;
  339. X
  340. X    for(temp = clist; temp && temp->c_next; temp=temp->c_next)
  341. X        if(!(rand()&1111))
  342. X            break;
  343. X    if(temp) {
  344. X        hold->c_next = temp->c_next;
  345. X        temp->c_next = hold;
  346. X    } else {
  347. X        hold->c_next = clist;
  348. X        clist = hold;
  349. X    }
  350. X}
  351. X
  352. Xdrops()
  353. X{
  354. X    int l, c;
  355. X    struct _c *hold;
  356. X    for(hold = clist; hold; hold=hold->c_next) {
  357. X        int line = hold->c_line, column=hold->c_column;
  358. X        if(line>= li-2 && column>=co-1) {
  359. X            newscreen[line][column] &= ~0200;
  360. X            screen[line][column] &= ~0200;
  361. X            hold->c_mark = 1;
  362. X            continue;
  363. X        }
  364. X        if(newscreen[line+1][column+1] == ' ' &&
  365. X           newscreen[line+1][column-1] == ' ')
  366. X            drop(line+1, column);
  367. X        drop(line, column+1);
  368. X        drop(line-1, column);
  369. X        drop(line, column-1);
  370. X        if(newscreen[line+1][column]==' ' ||
  371. X           (packflag &&
  372. X            newscreen[line+1][column]==(screen[line][column]&~0200)
  373. X           )
  374. X          ) {
  375. X            newscreen[line+1][column] = screen[line][column];
  376. X            newscreen[line][column] = ' ';
  377. X            line++;
  378. X        } else if(rand()&01000) {
  379. X            if(column>0 && newscreen[line][column-1] == ' ' &&
  380. X                newscreen[line+1][column-1]==' ') {
  381. X                newscreen[line][column-1] =
  382. X                    screen[line][column];
  383. X                newscreen[line][column] = ' ';
  384. X                column--;
  385. X            }
  386. X            else if(column<co-1 &&
  387. X                newscreen[line][column+1] == ' ' &&
  388. X                newscreen[line+1][column+1]==' ') {
  389. X                    newscreen[line][column+1] =
  390. X                        screen[line][column];
  391. X                    newscreen[line][column] = ' ';
  392. X                    column++;
  393. X            }
  394. X            else {
  395. X                screen[line][column] &= ~0200;
  396. X                newscreen[line][column] &= ~0200;
  397. X                hold -> c_mark = 1;
  398. X            }
  399. X        } else {
  400. X            if(column<co-1 && newscreen[line][column+1] == ' ' &&
  401. X                newscreen[line+1][column+1]==' ') {
  402. X                newscreen[line][column+1] =
  403. X                    screen[line][column];
  404. X                newscreen[line][column] = ' ';
  405. X                column++;
  406. X            }
  407. X            else if(column>0 && newscreen[line][column-1] == ' ' &&
  408. X                newscreen[line+1][column-1]==' ') {
  409. X                newscreen[line][column-1] =
  410. X                    screen[line][column];
  411. X                newscreen[line][column] = ' ';
  412. X                column--;
  413. X            }
  414. X            else {
  415. X                newscreen[line][column] &= ~0200;
  416. X                screen[line][column] &= ~0200;
  417. X                hold -> c_mark = 1;
  418. X            }
  419. X        }
  420. X        hold -> c_column = column;
  421. X        hold -> c_line = line;
  422. X        fflush(stdout);
  423. X    }
  424. X
  425. X    while(clist && clist->c_mark) {
  426. X        struct _c *p = clist;
  427. X        clist = clist -> c_next;
  428. X        free(p);
  429. X    }
  430. X    hold = clist;
  431. X    while(hold && hold->c_next)
  432. X        if(hold->c_next->c_mark) {
  433. X            struct _c *p = hold->c_next;
  434. X            hold->c_next = p->c_next;
  435. X            free(p);
  436. X        } else
  437. X            hold=hold->c_next;
  438. X}
  439. X
  440. Xdroplet(line, column)
  441. Xint line, column;
  442. X{
  443. X    int ret;
  444. X    if(line==li-1)
  445. X        return 0;
  446. X    while(column>=0 &&
  447. X          screen[line][column]!=' ' &&
  448. X          screen[line+1][column]==' ')
  449. X        column--;
  450. X    column++;
  451. X    while(column<co &&
  452. X          screen[line][column]!=' ' &&
  453. X          screen[line+1][column]==' ')
  454. X        drop(line, column++);
  455. X    ret = clist != 0;
  456. X    while(clist) {
  457. X        drops();
  458. X        update();
  459. X    }
  460. X    return ret;
  461. X}
  462. X
  463. Xdropscreen()
  464. X{
  465. X    int column, line;
  466. X    int rubbish = 0, count = 0;
  467. X
  468. X    do {
  469. X        int start, limit, incr;
  470. X        count++;
  471. X        rubbish = 0;
  472. X        if(count&1) { start=li-2; limit=0; incr = -1; }
  473. X        else { start=0; limit=li-2; incr=1; }
  474. X        for(line=start; line!=limit && !rubbish; line+=incr) {
  475. X            if(line&1)
  476. X                for(column=0; column<co && !rubbish; column++)
  477. X                    rubbish += droplet(line, column);
  478. X            else
  479. X                for(column=co-1; column>=0 && !rubbish; column--)
  480. X                    rubbish += droplet(line, column);
  481. X        }
  482. X    } while(rubbish);
  483. X}
  484. X
  485. Xdropf(file)
  486. Xchar *file;
  487. X{
  488. X    FILE *fp;
  489. X
  490. X    if(!(fp = fopen(file, "r"))) {
  491. X        perror(file);
  492. X        return -1;
  493. X    }
  494. X    fdropf(fp);
  495. X}
  496. X
  497. Xfdropf(fp)
  498. XFILE *fp;
  499. X{
  500. X    int i;
  501. X
  502. X    while(!feof(fp)) {
  503. X        readscreen(fp);
  504. X        drawscreen();
  505. X        for(i=0; i<20; i++)
  506. X            droplet((rand()>>4) % (li-1), (rand()>>4) % co);
  507. X        dropscreen();
  508. X    }
  509. X}
  510. X
  511. Xouts(s)
  512. Xchar *s;
  513. X{
  514. X    fputs(s, stdout);
  515. X}
  516. X
  517. Xmin(a, b)
  518. Xint a, b;
  519. X{
  520. X    if(a<b) return a;
  521. X    return b;
  522. X}
  523. END_OF_FILE
  524. if test 9548 -ne `wc -c <'rot.c'`; then
  525.     echo shar: \"'rot.c'\" unpacked with wrong size!
  526. fi
  527. # end of 'rot.c'
  528. fi
  529. echo shar: End of shell archive.
  530. exit 0
  531. -- 
  532.  _--_|\  `-_-' Peter da Silva. +1 713 274 5180.      <peter@ficc.uu.net>
  533. /      \  'U`  Have you hugged your wolf today?  <peter@sugar.hackercorp.com>
  534. \_.--._/
  535.       v        Disclaimer: People have opinions, organisations have policy.
  536.  
  537.  
  538.